package org.procrastinationapp.business.services.aaa.impl;

import java.util.List;

import org.jasypt.util.password.PasswordEncryptor;
import org.procrastinationapp.business.entities.user.User;
import org.procrastinationapp.business.entities.user.repositories.UserRepository;
import org.procrastinationapp.business.exceptions.aaa.IncorrectLoginException;
import org.procrastinationapp.business.services.aaa.AaaService;
import org.procrastinationapp.commons.exceptions.InternalErrorException;
import org.procrastinationapp.commons.exceptions.RequiredEntityNotFoundException;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.transaction.annotation.Transactional;

public class AaaServiceImpl implements AaaService {
	private String defaultPassword = null;
	private UserRepository userRepository = null;
	private PasswordEncryptor passwordEncryptor = null;

	@Required
	public void setDefaultPassword(String defaultPassword) {
		this.defaultPassword = defaultPassword;
	}

	@Required
	public void setUserRepository(UserRepository userRepository) {
		this.userRepository = userRepository;
	}

	@Required
	public void setPasswordEncryptor(PasswordEncryptor passwordEncryptor) {
		this.passwordEncryptor = passwordEncryptor;
	}

	@Transactional(readOnly = true)
	public User loginUser(String login, String password)
			throws IncorrectLoginException {

		User user = userRepository.getUser(login);

		if (user == null) {
			throw new IncorrectLoginException(login);
		}

		String storedPasswordDigest = userRepository.getPasswordForUser(login);

		if (passwordEncryptor.checkPassword(password, storedPasswordDigest)) {
			return user;
		}

		throw new IncorrectLoginException(login);

	}

	@Transactional
	public void changeUserPassword(String login, String currentPassword,
			String newPassword) throws IncorrectLoginException {

		String storedPasswordDigest = userRepository.getPasswordForUser(login);
		if (storedPasswordDigest == null) {
			throw new RequiredEntityNotFoundException(User.class.getName(),
					login);
		}

		if (passwordEncryptor.checkPassword(currentPassword,
				storedPasswordDigest)) {
			String newPasswordDigest = passwordEncryptor
					.encryptPassword(newPassword);
			userRepository.setPasswordForUser(login, newPasswordDigest);
		} else {
			throw new IncorrectLoginException(login);
		}
	}

	@Transactional(readOnly = true)
	public List<User> getUsers() {
		return userRepository.getUsers();
	}

	@Transactional(readOnly = true)
	public User getUser(String login) {
		return userRepository.getUser(login);
	}

	@Transactional
	public void addUser(User user, String password) {
		saveUser(user);
		try {
			changeUserPassword(user.getLogin(), defaultPassword, password);
		} catch (IncorrectLoginException e) {
			throw new InternalErrorException("Incorrect default password.");
		}
	}

	@Transactional
	public void saveUser(User user) {
		userRepository.saveUser(user);
	}

	@Transactional
	public void removeUser(String login) {
		userRepository.removeUser(login);
	}
}
